home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Documentation / DirectX9 / directx9_m.chm / directx / code / objectmembers2.js < prev    next >
Encoding:
Text File  |  2004-09-30  |  19.9 KB  |  645 lines

  1. //Load the config file.
  2. //The config contains the path to be walked or the path to an individual file.
  3. //The path to the data file to be updated.
  4.  
  5. WScript.Echo(new Date());                // echo when the code started.
  6.  
  7. var start = new Date();    //Used for perf testing
  8. var sDate=start.getHours() + ":" + start.getMinutes() + ":" + start.getSeconds() + ":" + start.getMilliseconds()
  9.  
  10. var warningCount = 0;
  11. var errorCount = 0;
  12.  
  13. var gScriptPath=WScript.ScriptFullName.substr(0,2);
  14. //gfs = new ActiveXObject("Scripting.FileSystemObject");
  15. var oArgs = WScript.Arguments;
  16. var gsConfigPath = oArgs(0);            //Config file
  17. var goIterator=new IteratorClass(gsConfigPath);
  18. goIterator.walk(goIterator.rootPath);
  19. //WScript.Echo(goIterator.fileCount);
  20. goIterator.done();
  21.  
  22. WScript.Echo("The number of errors are " + errorCount + ".");
  23. WScript.Echo("The number of warnings are " + warningCount + ".");
  24. WScript.Echo(new Date());                // echo when the code finished.
  25.  
  26. //Constructor for iterator object
  27. function IteratorClass(sConfigPath)
  28. {
  29.     this.fileCount=0;
  30.     this.fs = new ActiveXObject("Scripting.FileSystemObject");
  31.     this.datasets = new Array();
  32.     this.destinations= new Array();
  33.     this.configFile=getConfig(sConfigPath);
  34.     this.getDestination=getDestination;
  35.     this.destinationNodes=this.configFile.selectNodes("/root/datafile")
  36.     for (var i=0;i<this.destinationNodes.length;i++)
  37.     {
  38.         this.destinations[i]=new DestinationClass(this.destinationNodes.item(i))
  39.     }
  40.     this.providerNodes=this.configFile.selectNodes("/root/provider");
  41.     for (var i=0;i<this.providerNodes.length;i++)
  42.     {
  43.         var datasetName=this.providerNodes.item(i).getAttribute("datafilerid");
  44.         this.datasets[i]=new DataSetClass(this.configFile,this.providerNodes.item(i),this.getDestination(datasetName));
  45.         //WScript.Echo(this.datasets[i].name);
  46.     }
  47.     this.rootPath=this.configFile.selectSingleNode("/root/sourcefiles").text;
  48.     this.rootPath=EnsureDriveLetter(this.rootPath);
  49.     this.done=SaveAll;
  50.     this.passAround=passAround;
  51.     this.walk=recursWalk;
  52.     return this;
  53. }
  54.  
  55.  
  56. //Constructor for dataset object
  57. function DataSetClass(oConfigFile,providerNode,destination)
  58. {
  59.     //var start = new Date();    //Used for perf testing
  60.     //this.startTime=start.getHours() + ":" + start.getMinutes() + ":" + start.getSeconds() + ":" + start.getMilliseconds()
  61.     //this.endTime="";
  62.     this.queryID="";
  63.     this.fixedID="";
  64.     this.datasetName=providerNode.getAttribute("datafilerid");
  65.     this.name=providerNode.getAttribute("name");
  66.     this.configFile=oConfigFile;
  67.     //bugbug: These calls should use nodefromid
  68.     //var templatePath=this.configFile.selectSingleNode("/root/datafile[@id='" + this.datasetName + "']").getAttribute("template_path");
  69.     //this.outputPath=this.configFile.selectSingleNode("/root/datafile[@id='" + this.datasetName + "']").getAttribute("output_path");
  70.     //bugbug what if you cannot open the template- log the failure and end
  71.     this.template=destination    //getConfig(templatePath);
  72.     
  73.     this.qualifyingQueries= new Array();
  74.     var qualifyNodes=providerNode.selectNodes("./qualify");
  75.     for (var i=0;i<qualifyNodes.length;i++){
  76.         this.qualifyingQueries[i]=qualifyNodes.item(i).getAttribute("value");
  77.         //WScript.Echo(this.qualifyingQueries[i]);
  78.     }
  79.     
  80.     this.groups= new Array();
  81.     var groupNodes=providerNode.selectNodes("./group_by")    
  82.     for (var i=0;i<groupNodes.length;i++)
  83.     {
  84.         var g = groupNodes.item(i);
  85.         var nameCaption=g.getAttribute("namecaption")
  86.         var pnCaption=g.getAttribute("pncaption")
  87.         var gid = g.getAttribute("id");
  88.         var devlang = g.getAttribute("devlang");
  89.         
  90.         // peterril:  added capability to force unique entries
  91.         //              duplicates are possible in situations like a page is for both VB and Script
  92.         //              where they are both objects and they may match multiple criteria.
  93.         //
  94.         //              @unique can exist on a group or provider.
  95.         var unique = (g.getAttribute("unique") ||         
  96.                       g.selectSingleNode("..").getAttribute("unique") 
  97.                       ? true : false);
  98.         
  99.         if (!nameCaption) nameCaption="";    
  100.         if (!pnCaption) pnCaption="";
  101.         if (!devlang) devlang="";
  102.             
  103.         this.groups[i]=new GroupClass(groupNodes.item(i).getAttribute("id"), 
  104.                                       groupNodes.item(i).getAttribute("name"),
  105.                                       groupNodes.item(i).getAttribute("value"), 
  106.                                       nameCaption, pnCaption, devlang);
  107.         this.groups[i].unique = unique;
  108.     }
  109.  
  110.     this.customPolls = new Array();
  111.     var customPollNodes = providerNode.selectNodes("./dyndesc");
  112.     for( var i=0; i<customPollNodes.length; i++ ){
  113.         this.customPolls[i] = new Object();
  114.         //this.customPolls[i].name = customPollNodes.item(i).getAttribute("name");
  115.         this.customPolls[i].value = customPollNodes.item(i).getAttribute("value");
  116.     }
  117.     
  118.     this.queryID=ensureAttribute(providerNode,"query_id");
  119.     this.fixedID=ensureAttribute(providerNode,"fixed_id");
  120.     //WScript.Echo(this.queryID);
  121.     //WScript.Echo(this.fixedID);
  122.     this.process=process;
  123.     this.qualifies=qualifies;
  124.     //this.save=save;
  125.     this.updateDataFromDoc=updateDataFromDoc;
  126.     this.getGroupName=getGroupName;
  127.     this.getGroup=getGroup;
  128.     this.ensureObject=ensureObject;
  129.     return this;
  130. }
  131.  
  132. function getDestination(destinationName)
  133. {
  134.     for (var i=0;i<this.destinations.length;i++)
  135.     {
  136.         if (this.destinations[i].name==destinationName)
  137.         {
  138.             return this.destinations[i].template
  139.         }
  140.     }
  141.     //bugbug: What about failure?
  142. }
  143.  
  144. //Constructor for the destination class
  145. function DestinationClass(destinationNode)
  146. {
  147.     var start = new Date();    //Used for perf testing
  148.     this.startTime=start.getHours() + ":" + start.getMinutes() + ":" + start.getSeconds() + ":" + start.getMilliseconds()
  149.     this.name=destinationNode.getAttribute("id");
  150.     this.outputPath=destinationNode.getAttribute("output_path");
  151.     this.template=getConfig(EnsureDriveLetter(destinationNode.getAttribute("template_path")));
  152.     this.outputPath=EnsureDriveLetter(this.outputPath);
  153.     return this
  154. }
  155.  
  156. function EnsureDriveLetter(sPath)
  157. {
  158.     if (sPath.substr(1,1)!=":")
  159.     {
  160.         return gScriptPath + sPath;
  161.     }
  162.     else
  163.     {
  164.         return sPath;
  165.     }
  166. }
  167.  
  168. function SaveAll()
  169. {
  170.     var fso = new ActiveXObject("Scripting.FileSystemObject");
  171.  
  172.     var end = new Date();
  173.     var sDate= end.getHours() + ":" + end.getMinutes() + ":" + end.getSeconds() + ":" + end.getMilliseconds()
  174.     for (var i=0;i<this.destinationNodes.length;i++)
  175.     {
  176.         this.destinations[i].template.documentElement.setAttribute("StartTime",this.destinations[i].startTime);
  177.         this.destinations[i].template.documentElement.setAttribute("EndTime",sDate);
  178.  
  179.         // make sure the file is not read-only.
  180.         if (fso.FileExists(this.destinations[i].outputPath))
  181.             fso.GetFile(this.destinations[i].outputPath).Attributes = 0;
  182.  
  183.         this.destinations[i].template.save(this.destinations[i].outputPath);
  184.     }
  185. }
  186.  
  187. function passAround(sPath)
  188. {
  189.     WScript.Echo(sPath);
  190.     
  191.     var xmlDoc=getConfig(sPath);
  192.     if( xmlDoc.parseError != 0 ){
  193.         WScript.Echo( ".... ERROR: Unable to validate ('" + xmlDoc.parseError.reason + "')" );
  194.         errorCount++;
  195.         return;
  196.     }
  197.     
  198.     for (var i=0;i<this.providerNodes.length;i++)
  199.     {
  200.         this.datasets[i].process(xmlDoc);
  201.     }    
  202. }
  203.  
  204. function recursWalk(sPath){        //recursively walk the tree and process each xml file
  205.     var colFiles=this.fs.GetFolder(sPath).files
  206.     var enumFiles=new Enumerator(colFiles)
  207.     for (;!enumFiles.atEnd(); enumFiles.moveNext())
  208.     {
  209.         var oFile=enumFiles.item();
  210.         if (oFile.path.toLowerCase().indexOf(".xml") != -1)
  211.         {
  212.             //update(oFile.path);
  213.             this.passAround(oFile.path);
  214.             this.fileCount++;
  215.         }
  216.     }
  217.     var colFolders=this.fs.GetFolder(sPath).SubFolders
  218.     if (colFolders)
  219.     {
  220.         var enumFolders=new Enumerator(colFolders)
  221.         for (;!enumFolders.atEnd(); enumFolders.moveNext())
  222.         {
  223.             var oFolder=enumFolders.item();
  224.             this.walk(oFolder.path);
  225.         }
  226.     }
  227. }
  228.  
  229. //process is a member of the DataSetClass
  230. function process(xmlDoc)
  231. {
  232.     //Does the document qualify?
  233.     if (this.qualifies(xmlDoc))
  234.     {
  235.         //get the data and insert it into the output file
  236.         this.updateDataFromDoc(xmlDoc)
  237.     }
  238. }
  239.  
  240. function qualifies(xmlDoc)
  241. {
  242.     sResult=true;
  243.     for (var i=0;i<this.qualifyingQueries.length;i++)
  244.     {
  245.         if(this.qualifyingQueries[i]){
  246.             try{
  247.                 var testNode=xmlDoc.selectSingleNode(this.qualifyingQueries[i]);
  248.                 if (!testNode)
  249.                 {
  250.                     //WScript.Echo(xmlDoc.url + " fails " + this.qualifyingQueries[i] + " of " + this.name);
  251.                     sResult=false;
  252.                     return sResult;
  253.                 }
  254.             } catch(e) {
  255.                 WScript.Echo( ".... ERROR: Unable to qualify provider '" + this.name + "' ('" + e.message + "')" );
  256.                 errorCount++;
  257.                 this.qualifyingQueries[i] = null;
  258.                 sResult = false;
  259.             }
  260.         }
  261.     }
  262.     return sResult;
  263. }
  264.  
  265.  
  266. function save()
  267. {
  268.     var end = new Date();
  269.     var sDate= end.getHours() + ":" + end.getMinutes() + ":" + end.getSeconds() + ":" + end.getMilliseconds()
  270.     this.template.documentElement.setAttribute("StartTime",this.startTime);
  271.     this.template.documentElement.setAttribute("EndTime",sDate);
  272.  
  273.     // make sure the file is not read-only.
  274.     if (fso.FileExists(this.outputPath))
  275.         fso.GetFile(this.outputPath).Attributes = 0;
  276.  
  277.     this.template.save(this.outputPath);    
  278. }
  279.  
  280. function ensureAttribute(oNode,sAttribute)
  281. {
  282.     var sResult=oNode.getAttribute(sAttribute);
  283.     if (sResult)
  284.     {
  285.         return sResult;
  286.     }
  287.     else
  288.     {
  289.         return "";
  290.     }
  291. }
  292.  
  293. function GroupClass(sID, sName, sQuery, sNameCaption, sPNCaption, devlang)
  294. {
  295.     this.id=sID;
  296.     this.name=sName;
  297.     this.query=sQuery;
  298.     this.nameCaption=sNameCaption;
  299.     this.pnCaption=sPNCaption;
  300.     this.devlang=devlang;
  301.     return this;
  302. }
  303.  
  304. //returns the XMLdocument that is the configuration file
  305. function getConfig(sConfigPath)
  306. {
  307.     var oConfigFile = new ActiveXObject("Microsoft.XMLDOM");
  308.     oConfigFile.resolveExternals=true;
  309.     oConfigFile.validateOnParse=true;
  310.     oConfigFile.async=false;
  311.     oConfigFile.load(sConfigPath);
  312.     var parseErr=oConfigFile.parseError;
  313.     if (parseErr.errorCode != 0)
  314.     {
  315.         var reason=parseErr.reason
  316.         var line=parseErr.line
  317.         var srcText=parseErr.srcText
  318.         //WScript.Echo(reason + " " + line + " " + srcText);
  319.     }
  320.     return oConfigFile;
  321. }
  322.  
  323. function updateDataFromDoc(sourceDoc)
  324. {
  325.     //Gather up the key pieces of this member to be inserted into all it's parent objects and interfaces
  326.     var sRid=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@id").value;
  327.     
  328.     if(sRid != this.fixedID && sRid != this.queryID){
  329.         var oPN=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@pn");
  330.         var oOverloaded=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@overloaded");
  331.         var oProdRid = sourceDoc.selectSingleNode("/inetsdk:topic/content/info/product/@rid");
  332.         var oMinver = sourceDoc.selectSingleNode("/inetsdk:topic/content/info/product/@minver");
  333.         var sSortKey = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@name").value;
  334.  
  335.         if(oPN)
  336.             var sPN=oPN.value;
  337.  
  338.         if (oOverloaded)
  339.             var oParams = sourceDoc.selectNodes("/inetsdk:topic/content/params");
  340.  
  341.         if (oProdRid)
  342.             var sProdRid = oProdRid.value;
  343.  
  344.         if (oMinver)
  345.             var sMinver = oMinver.value;
  346.  
  347.         // peterril (11/1/01):  This is added because of a request from GDI+.
  348.         var tmp = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/data[@name $eq$ 'sort']");
  349.         if(tmp)
  350.             sSortKey = tmp.getAttribute("value");
  351.  
  352.         //bugbug: member element needs to be a child of member type element
  353.         var sType=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@type").value
  354.  
  355.         // peterril:  special case happens when a page is only an attribute.    
  356.         var sName = "";
  357.         if( sType != "attribute" )
  358.             sName=sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@name").value
  359.  
  360.         // Use alternative name where available (currently only for script command ids)
  361.         var sAltName = "";
  362.         var oName = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/devlang[@value='scr']/@name");
  363.         if ( oName )
  364.           sAltName = oName.value;
  365.  
  366.         var oDesc = pollCustom( this.customPolls, sourceDoc);
  367.         if( !oDesc )
  368.             oDesc=sourceDoc.selectSingleNode("/inetsdk:topic/content/desc");            // try to get main description.
  369.         if( !oDesc ){
  370.             oDesc=sourceDoc.selectSingleNode("/inetsdk:topic//abstract");            // common in overviews.
  371.     
  372.             // -peterril-
  373.             // the only way I know to rename a node is to create a new one and transfer the information.
  374.             // 
  375.             // the reason that I rename the node is because I wanted to maintain consistancy with the
  376.             // objectmembers code.  This way, the objectmembers code can always assume a desc.
  377.             //
  378.             if( oDesc ){
  379.                 var t = oDesc;
  380.                 oDesc = sourceDoc.createElement("desc");
  381.                 var t = t.firstChild;
  382.                 while(t){
  383.                     oDesc.appendChild( t.cloneNode(true) );
  384.                     t = t.nextSibling;
  385.                 }
  386.             }
  387.         }
  388.         if( !oDesc )
  389.             oDesc = sourceDoc.createElement("desc");        // create blank description.
  390.  
  391.  
  392.         var bNotSupported = (sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@not_supp") ? true : false);
  393.         var bNotImplemented = (sourceDoc.selectSingleNode("/inetsdk:topic/metadata/@not_impl") ? true : false);
  394.     
  395.         if( bNotSupported )
  396.             oDesc.text = "Not currently supported.";
  397.         else if( bNotImplemented )
  398.             oDesc.text = "Not currently implemented.";
  399.  
  400.         var oDescClone;
  401.  
  402.         if (this.fixedID!="")
  403.         {
  404.             var group=this.getGroup(sourceDoc);
  405.             if (!group) return;
  406.  
  407.             var objectNode=this.ensureObject(this.fixedID,group);
  408.             if ( group.devlang != "" )
  409.               objectNode.setAttribute( "devlang", group.devlang );
  410.  
  411.             var member=this.template.createElement("member")
  412.             member.setAttribute("rid",sRid);
  413.             if(sName) member.setAttribute("name",sName);
  414.             if ( sAltName != "" ) member.setAttribute( "altname", sAltName );
  415.             member.setAttribute("sortkey", sSortKey);
  416.             if (oPN) member.setAttribute("pn", sPN);
  417.             if (oProdRid) member.setAttribute("prodrid", sProdRid);
  418.             if (oMinver) member.setAttribute("minver", sMinver);
  419.  
  420.             var oDispID = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/applies/iface[@rid = '" + parentID + "']/@dispid");
  421.             if( oDispID ) var sDispID = oDispID.value;
  422.                 
  423.             if(oDispID) member.setAttribute("dispid", sDispID);
  424.  
  425.             member.setAttribute("type",sType);
  426.             objectNode.appendChild(member);
  427.  
  428.             if (oDesc){
  429.                 if( oDesc[0] ){
  430.                     for( var j=0; j<oDesc.length; j++ ){
  431.                         oDescClone = oDesc[j].cloneNode(true);
  432.                         member.appendChild(oDescClone);
  433.                     }
  434.                 } else {
  435.                     oDescClone=oDesc.cloneNode(true);
  436.                     member.appendChild(oDescClone);        //Add this member to the object
  437.                     
  438.                     if( !oDesc.firstChild ){        // echo warning that there is no description.
  439.                         WScript.Echo(".... WARNING: A default description was created because none existed in document.");
  440.                         warningCount++;
  441.                     }
  442.                 }
  443.             } else {
  444.                 WScript.Echo( ".... ERROR: Unable to retrieve required description." );
  445.                 errorCount++;
  446.             }
  447.  
  448.             if (oOverloaded)
  449.             {
  450.                 for (i = 0; i < oParams.length; i++)
  451.                     member.appendChild(oParams[i].cloneNode(true));
  452.             }
  453.         }
  454.         else        //BUGBUG: Missing dispid from the ifaces and autoiid on the members.
  455.         {
  456.             var group=this.getGroup(sourceDoc);
  457.             if (!group) return;
  458.                 
  459.             var parentNodes=sourceDoc.selectNodes(this.queryID);
  460.             for (var i=0;i<parentNodes.length;i++)
  461.             {
  462.                 var parentID=parentNodes[i].text
  463.                 var oAIs = parentNodes[i].selectNodes("../accessinfo");    // hack to go back up to parent tag.
  464.                 var oAIClone = null;
  465.                 var objectNode=this.ensureObject(parentID, group, group.devlang);
  466.                 
  467.                 //peterril: check to verify that there are no duplicates if set in config.
  468.                 var isUnique = true;
  469.                 if( group.unique ) isUnique = isUniqueRecord( sRid, objectNode );
  470.                 
  471.                 if( !isUnique )
  472.                 {
  473.                     WScript.Echo(".... ERROR: Discarded record because uniquness was enforced [" + parentID + "].");
  474.                     errorCount++;
  475.                 }
  476.                 else
  477.                 {
  478.                     if ( group.devlang != "" )
  479.                         objectNode.setAttribute( "devlang", group.devlang );
  480.  
  481.                     var member = this.template.createElement("member");
  482.                     member.setAttribute("rid",sRid);
  483.                     if(sName) member.setAttribute("name",sName);
  484.                     if ( sAltName != "" ) member.setAttribute( "altname", sAltName );
  485.                     member.setAttribute("sortkey", sSortKey);
  486.                     if(oPN) member.setAttribute("pn",sPN);
  487.                     if(oMinver) member.setAttribute("minver",sMinver);
  488.  
  489.                     var oDispID = sourceDoc.selectSingleNode("/inetsdk:topic/metadata/applies/iface[@rid = '" + parentID + "']/@dispid");
  490.                     if( oDispID ) var sDispID = oDispID.value;
  491.                 
  492.                     if(oDispID) member.setAttribute("dispid", sDispID);
  493.                     member.setAttribute("type",sType);
  494.                     objectNode.appendChild(member);
  495.  
  496.                     // insert description information.
  497.                     if (oDesc){
  498.                         if( oDesc[0] ){
  499.                             for( var j=0; j<oDesc.length; j++ ){
  500.                                 oDescClone = oDesc[j].cloneNode(true);
  501.                                 member.appendChild(oDescClone);
  502.                             }
  503.                         } else {
  504.                             oDescClone=oDesc.cloneNode(true);
  505.                             member.appendChild(oDescClone);        //Add this member to the object
  506.                             
  507.                             if( !oDesc.firstChild ){        // echo warning that there is no description.
  508.                                 WScript.Echo(".... WARNING: A default description was created because none existed in document.");
  509.                                 warningCount++;
  510.                             }
  511.                         }
  512.                     } else {
  513.                         WScript.Echo( ".... ERROR: Unable to retrieve required description." );
  514.                         errorCount++;
  515.                     }
  516.  
  517.                     // insert accessinfo information.
  518.                     for( var j=0; j<oAIs.length; j++ ){
  519.                         var oAI = oAIs[j];
  520.                         oAIClone = oAI.cloneNode( true );
  521.                         member.appendChild( oAIClone );
  522.                     }
  523.                     
  524.                     if (oOverloaded)
  525.                     {
  526.                         for (i = 0; i < oParams.length; i++)
  527.                             member.appendChild(oParams[i].cloneNode(true));
  528.                     }
  529.                 }
  530.             }
  531.         }
  532.     }
  533. }
  534.  
  535. function isUniqueRecord(idToFind, sourceData){
  536.     var result = true;
  537.     
  538.     if(idToFind && sourceData){
  539.         var t = sourceData.selectSingleNode("member[@rid='" + idToFind + "']");
  540.         if(t) result = false;
  541.     }
  542.     
  543.     return result;
  544. }
  545.  
  546. function pollCustom( aPollsFound, sourceDoc ){
  547.     for( var i=0; i<aPollsFound.length; i++ ){
  548.         var searchValue = aPollsFound[i].value;
  549.         
  550.         var foundNodes = sourceDoc.selectNodes( searchValue );
  551.         
  552.         if( foundNodes.length >= 1 )
  553.             return renameNode(foundNodes[i], "desc");
  554.         else 
  555.             return null;
  556.     }
  557. }
  558.  
  559. function renameNode( srcNode, newName ){
  560.     var xml = new ActiveXObject("Microsoft.XMLDOM");
  561.     
  562.     if( srcNode && newName ){
  563.         if( srcNode.nodeName == newName )
  564.             return srcNode.cloneNode(true);
  565.         
  566.         var t = xml.createElement(newName);
  567.         var c = srcNode.firstChild;
  568.         while(c){
  569.             t.appendChild(c.cloneNode(true));
  570.             c = c.nextSibling;
  571.         }
  572.         
  573.         for( var i=0; i<srcNode.attributes.length; i++ ){
  574.             var att = srcNode.attributes[i];
  575.             t.setAttribute( att.nodeName, att.nodeValue );
  576.         }
  577.         
  578.         return t;
  579.     } else 
  580.         return null;
  581. }
  582.  
  583. function ensureObject(sParentID, oType, devlang){
  584.     //var objectNode=this.template.selectSingleNode("/objectmembers/parent[@id='" + sParentID + "']")
  585.     var objectNode=this.template.nodeFromID(sParentID)
  586.     if (!objectNode)
  587.     {
  588.         objectNode=this.template.createElement("parent")
  589.         this.template.documentElement.appendChild(objectNode)
  590.         objectNode.setAttribute("id",sParentID);
  591.     }
  592.     
  593.     var typeNode = "";
  594.     if(devlang)
  595.         typeNode=this.template.selectSingleNode("/objectmembers/parent[@id='" + sParentID + "']/type[@gid='" + oType.id + "' $and$ @devlang='" + devlang + "']")
  596.     else
  597.         typeNode=this.template.selectSingleNode("/objectmembers/parent[@id='" + sParentID + "']/type[@gid='" + oType.id + "']")
  598.     if (!typeNode)
  599.     {
  600.         typeNode=this.template.createElement("type")
  601.         objectNode.appendChild(typeNode)
  602.         typeNode.setAttribute("value",oType.name);
  603.         typeNode.setAttribute("namecaption",oType.nameCaption);
  604.         typeNode.setAttribute("gid", oType.id);
  605.         typeNode.setAttribute("pncaption",oType.pnCaption);
  606.         if(devlang) typeNode.setAttribute("devlang", devlang);
  607.     }
  608.     return typeNode;
  609. }
  610.  
  611. function getGroupName(xmlDoc)
  612. {
  613.     var sResult="unknown";
  614.     for (var i=0;i<this.groups.length;i++)
  615.     {
  616.         if (xmlDoc.selectSingleNode(this.groups[i].query))
  617.         {
  618.             sResult=this.groups[i].name;
  619.             break;
  620.         }
  621.     }
  622.     return sResult;
  623. }
  624.  
  625. function getGroup(xmlDoc)
  626. {
  627.     for (var i=0;i<this.groups.length;i++)
  628.     {
  629.         if(this.groups[i].query){
  630.             try{
  631.                 if (xmlDoc.selectSingleNode(this.groups[i].query))
  632.                 {
  633.                     return this.groups[i];
  634.                 }
  635.             } catch(e) {
  636.                 WScript.Echo( ".... ERROR: Unable to qualify provider '" + this.name + "' ('" + e.message + "')" );
  637.                 errorCount++;
  638.                 this.groups[i].query = null;
  639.                 return null;
  640.             }
  641.         }
  642.     }
  643. }
  644.  
  645.